package com.cbs.android.component.weather.xinzhi;


import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

import com.cbs.android.component.log.L;
import com.cbs.android.component.network.HttpClient;
import com.cbs.android.component.network.Request;
import com.cbs.android.component.network.SimpleResponseHandler;
import com.cbs.android.component.network.decoder.GsonDecoder;
import com.cbs.android.component.weather.weatherinterface.WeatherHandler;
import com.cbs.android.component.weather.weatherinterface.WeatherInterface;
import com.cbs.android.component.weather.weatherinterface.constant.WeatherType;
import com.cbs.android.component.weather.weatherinterface.constant.WindDirection;
import com.cbs.android.component.weather.weatherinterface.constant.WindLevel;
import com.cbs.android.component.weather.weatherinterface.entity.Forecast;
import com.cbs.android.component.weather.weatherinterface.entity.Weather;
import com.cbs.android.component.weather.xinzhi.entity.XinzhiWeather;

import java.text.SimpleDateFormat;
import java.util.List;

/**
 * Created by zyj on 2016/9/21.
 */
public class Xinzhi implements WeatherInterface {
	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
	private static final String TAG = Xinzhi.class.getName();
	private String xinzhikey = "";
	private String xinzhiUrlTpl = "https://api.thinkpage.cn/v3/weather/daily.json?key=%s&location=%s&start=0&days=3";
	private HttpClient httpClient = (new HttpClient.Builder()).build();

	private Forecast forecast;
	private WeatherHandler weatherListener;
	private String msg;

	public Xinzhi(Context context) {
		try {
			ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
			xinzhikey = applicationInfo.metaData.getString("XINZHI_KEY");
		} catch (PackageManager.NameNotFoundException e) {
			L.e(TAG, "", e);
		}
	}

	@Override
	public void getForecast(final double lat, final double lng, WeatherHandler weatherListener) {
		msg = null;
		this.weatherListener = weatherListener;
		forecast = new Forecast();
		forecast.setLatitude(lat);
		forecast.setLongitude(lng);
//        httpClient.setDebug(true);
		Request xinzhirequest = new Request(String.format(xinzhiUrlTpl, xinzhikey, lat + ":" + lng))
				.setDecoder(new GsonDecoder(XinzhiWeather.class))
				.setResponseHandler(new SimpleResponseHandler<XinzhiWeather>() {
										@Override
										public void onSuccess(XinzhiWeather entity) {
											if (entity.getResults() != null && entity.getResults().size() > 0) {
												XinzhiWeather.ResultsEntity resultsEntity = entity.getResults().get(0);
												XinzhiWeather.ResultsEntity.LocationEntity locationEntity = resultsEntity.getLocation();
												forecast.setCityName(locationEntity.getName());
												if (resultsEntity.getDaily() != null) {
													for (XinzhiWeather.ResultsEntity.DailyEntity dailyEntity : resultsEntity.getDaily()) {
														try {
															long timestamp = simpleDateFormat.parse(dailyEntity.getDate()).getTime() / 1000;
															Weather weather = checkExisted(forecast.getWeathers(), timestamp);
															if (weather == null) {
																weather = new Weather();
																forecast.getWeathers().add(weather);
															}
															weather.setTimestamp(timestamp);

															weather.setTemperatureMin(Float.parseFloat(dailyEntity.getLow()));
															weather.setTemperatureMax(Float.parseFloat(dailyEntity.getHigh()));
//                                                            weather.setPrecipitation(Float.parseFloat(dailyEntity.getPrecip()));
															if (dailyEntity.getWind_speed() == null || dailyEntity.getWind_speed().equals("")) {
																weather.setWindLevel(WindLevel.UNKNOW);
															} else {
																weather.setWindLevel(WindLevel.fromSpeed(Double.parseDouble(dailyEntity.getWind_speed()) * 1000d / 3600d));
															}
															if (dailyEntity.getWind_direction_degree() == null || dailyEntity.getWind_direction_degree().equals("")) {
																weather.setWindDirection(WindDirection.UNKNOW);
															} else {
																weather.setWindDirection(WindDirection.fromAngle(Double.parseDouble(dailyEntity.getWind_direction_degree())));
															}

															if (dailyEntity.getCode_day() == null || dailyEntity.getCode_day().equals("")) {
																weather.setWeatherType(WeatherType.UNKNOW);
															} else {
																int code = Integer.parseInt(dailyEntity.getCode_day());
																switch (code) {
																	case 0:
																	case 1:
																	case 2:
																	case 3:
																	case 38:
																		weather.setWeatherType(WeatherType.CLEAR);
																		break;
																	case 4:
																	case 5:
																	case 6:
																	case 7:
																	case 8:
																		weather.setWeatherType(WeatherType.PARTLY_CLOUDY);
																		break;
																	case 9:
																	case 37:
																		weather.setWeatherType(WeatherType.CLOUDY);
																		break;
																	case 10:
																	case 11:
																	case 12:
																	case 13:
																	case 14:
																	case 15:
																	case 16:
																	case 17:
																	case 18:
																	case 19:
																		weather.setWeatherType(WeatherType.RAIN);
																		break;
																	case 20:
																	case 21:
																	case 22:
																	case 23:
																	case 24:
																	case 25:
																		weather.setWeatherType(WeatherType.SNOW);
																		break;
																	case 32:
																	case 33:
																	case 34:
																	case 35:
																	case 36:
																		weather.setWeatherType(WeatherType.WIND);
																		break;
																	case 30:
																		weather.setWeatherType(WeatherType.FOG);
																		break;
																	case 26:
																	case 27:
																	case 28:
																	case 29:
																	case 31:
																		weather.setWeatherType(WeatherType.HAZE);
																		break;
																	default:
																		weather.setWeatherType(WeatherType.CLEAR);
																}
															}


														} catch (Exception e) {
															// TODO what to do
															if (msg == null) {
																msg = "获取失败, 请稍后再试";
															}
														}
													}
												} else {
													if (msg == null) {
														msg = "获取失败, 请稍后再试";
													}
												}
											} else {
												if (msg == null) {
													msg = "获取失败, 请稍后再试";
												}
											}
											showWeather();
										}

										@Override
										public void onFailure(int code, String message) {
											if (msg == null) {
												msg = "获取失败, 请稍后再试";
											}
											showWeather();
										}

										@Override
										public void onException(Request request, Exception e) {
											super.onException(request, e);
											if (msg == null) {
												msg = "获取失败, 请稍后再试";
											}
											showWeather();
										}
									}

				);
		httpClient.send(xinzhirequest);
	}


	@Override
	public void getForecast(String cityCode, WeatherHandler weatherListener) {
//        Request request = new Request(String.format(urlTpl, key, cityCode))
//                .setDecoder(new GsonDecoder(CaiyunWeather.class))
//                .setResponseHandler(new ForecastResponseHandler(cityCode, 0, weatherListener));
//        httpClient.send(request);
	}

	@Override
	public void getForecastByCityName(String cityName, WeatherHandler weatherListener) {
		msg = null;
		this.weatherListener = weatherListener;
		forecast = new Forecast();
//        httpClient.setDebug(true);
		Request xinzhirequest = new Request(String.format(xinzhiUrlTpl, xinzhikey, cityName))
				.setDecoder(new GsonDecoder(XinzhiWeather.class))
				.setResponseHandler(new SimpleResponseHandler<XinzhiWeather>() {
										@Override
										public void onSuccess(XinzhiWeather entity) {
											if (entity.getResults() != null && entity.getResults().size() > 0) {
												XinzhiWeather.ResultsEntity resultsEntity = entity.getResults().get(0);
												XinzhiWeather.ResultsEntity.LocationEntity locationEntity = resultsEntity.getLocation();
												forecast.setCityName(locationEntity.getName());
												if (resultsEntity.getDaily() != null) {
													for (XinzhiWeather.ResultsEntity.DailyEntity dailyEntity : resultsEntity.getDaily()) {
														try {
															long timestamp = simpleDateFormat.parse(dailyEntity.getDate()).getTime() / 1000;
															Weather weather = checkExisted(forecast.getWeathers(), timestamp);
															if (weather == null) {
																weather = new Weather();
																forecast.getWeathers().add(weather);
															}
															weather.setTimestamp(timestamp);

															weather.setTemperatureMin(Float.parseFloat(dailyEntity.getLow()));
															weather.setTemperatureMax(Float.parseFloat(dailyEntity.getHigh()));
//                                                            weather.setPrecipitation(Float.parseFloat(dailyEntity.getPrecip()));
															if (dailyEntity.getWind_speed() == null || dailyEntity.getWind_speed().equals("")) {
																weather.setWindLevel(WindLevel.UNKNOW);
															} else {
																weather.setWindLevel(WindLevel.fromSpeed(Double.parseDouble(dailyEntity.getWind_speed()) * 1000d / 3600d));
															}
															if (dailyEntity.getWind_direction_degree() == null || dailyEntity.getWind_direction_degree().equals("")) {
																weather.setWindDirection(WindDirection.UNKNOW);
															} else {
																weather.setWindDirection(WindDirection.fromAngle(Double.parseDouble(dailyEntity.getWind_direction_degree())));
															}
															if (dailyEntity.getPrecip() != null && !dailyEntity.getPrecip().equals("")) {
																weather.setPrecipitation(Float.parseFloat(dailyEntity.getPrecip()));
															}

															if (dailyEntity.getCode_day() == null || dailyEntity.getCode_day().equals("")) {
																weather.setWeatherType(WeatherType.UNKNOW);
															} else {
																int code = Integer.parseInt(dailyEntity.getCode_day());
																switch (code) {
																	case 0:
																	case 1:
																	case 2:
																	case 3:
																	case 38:
																		weather.setWeatherType(WeatherType.CLEAR);
																		break;
																	case 4:
																	case 5:
																	case 6:
																	case 7:
																	case 8:
																		weather.setWeatherType(WeatherType.PARTLY_CLOUDY);
																		break;
																	case 9:
																	case 37:
																		weather.setWeatherType(WeatherType.CLOUDY);
																		break;
																	case 10:
																	case 11:
																	case 12:
																	case 13:
																	case 14:
																	case 15:
																	case 16:
																	case 17:
																	case 18:
																	case 19:
																		weather.setWeatherType(WeatherType.RAIN);
																		break;
																	case 20:
																	case 21:
																	case 22:
																	case 23:
																	case 24:
																	case 25:
																		weather.setWeatherType(WeatherType.SNOW);
																		break;
																	case 32:
																	case 33:
																	case 34:
																	case 35:
																	case 36:
																		weather.setWeatherType(WeatherType.WIND);
																		break;
																	case 30:
																		weather.setWeatherType(WeatherType.FOG);
																		break;
																	case 26:
																	case 27:
																	case 28:
																	case 29:
																	case 31:
																		weather.setWeatherType(WeatherType.HAZE);
																		break;
																	default:
																		weather.setWeatherType(WeatherType.CLEAR);
																}
															}


														} catch (Exception e) {
															// TODO what to do
															if (msg == null) {
																msg = "获取失败, 请稍后再试";
															}
														}
													}
												} else {
													if (msg == null) {
														msg = "获取失败, 请稍后再试";
													}
												}
											} else {
												if (msg == null) {
													msg = "获取失败, 请稍后再试";
												}
											}
											showWeather();
										}

										@Override
										public void onFailure(int code, String message) {
											if (msg == null) {
												msg = "获取失败, 请稍后再试";
											}
											showWeather();
										}

										@Override
										public void onException(Request request, Exception e) {
											super.onException(request, e);
											if (msg == null) {
												msg = "获取失败, 请稍后再试";
											}
											showWeather();
										}
									}

				);
		httpClient.send(xinzhirequest);
	}

	private Weather checkExisted(List<Weather> weathers, long timestamp) {
		for (Weather weather : weathers) {
			if (weather.getTimestamp() == timestamp) {
				return weather;
			}
		}
		return null;
	}

	private void showWeather() {
		if (msg != null) {
			weatherListener.onError(msg);
		} else {
			weatherListener.onForecast(forecast);
		}
	}
}
